package cn.edu.sdjzu.controller;

import cn.edu.sdjzu.entity.User;
import cn.edu.sdjzu.entity.authority.Role;
import cn.edu.sdjzu.entity.authority.UserAssRole;
import cn.edu.sdjzu.factory.ServiceFactory;
import cn.edu.sdjzu.service.impl.UserAssRoleServiceImpl;
import cn.edu.sdjzu.service.UserService;
import cn.edu.sdjzu.util.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.TreeSet;

@WebServlet("/login.ctl")
public class LoginCtrl extends HttpServlet {
    /**
     * JSON请求体
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //设置响应字符编码为UTF-8
        response.setContentType("application/json;charset=UTF-8");
        //将request body转换为JSON字串
        String user_json = JSONUtil.getJSON(request);
        //将JSON字串解析为User对象
        User userToLogin = JSON.parseObject(user_json, User.class);

        //创建JSON对象message，以便往前端响应信息
        JSONObject message = new JSONObject();

        try {
            ServiceFactory.getService(UserService.class, "UserServiceImpl").login(userToLogin);
            if (userToLogin.getId() == null) {
                message.put("msg", "用户不存在/密码错误");
                message.put("code","500");
                response.getWriter().println(JSON.toJSONString(message));
                return;
            } else {
                User currentUser = userToLogin;
                final UserAssRoleServiceImpl userAssRoleServiceImpl = ServiceFactory.getService(UserAssRoleServiceImpl.class, "UserAssRoleServiceImpl");
                Collection<UserAssRole> userAssRoleCollection = userAssRoleServiceImpl.findAll(currentUser);
                Collection<Role> roles = new TreeSet<>();
                for (UserAssRole userAssRole : userAssRoleCollection) {
                    Role role = userAssRole.getRole();
                    roles.add(role);
                }
//                message.put("actor", userToLogin);
                //输出JSON字串时，屏蔽某些字段
//                SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
                //不输出"department"、"title"和"degree"
//                filter.getExcludes().add("department");
//                filter.getExcludes().add("title");
//                filter.getExcludes().add("degree");

                //jwt对象
                JWTCreator.Builder builder = JWT.create();
                //指定算法为HMAC256，并传入一个秘钥
                Algorithm algorithm = Algorithm.HMAC256("XG22");
                //生成token
                Integer currentUserId = userToLogin.getId();
                String token = builder
                        //有效时间为30分钟
                        .withSubject("" + currentUserId)
                        .withExpiresAt(new Date(new Date().getTime() + (1000 * 60 * 30)))
                        //执行加密算法
                        .sign(algorithm);
                //构建响应信息
                message.put("msg", "操作成功");
                message.put("code","200");
                message.put("token",token);

                //响应正常数据
                response.getWriter().println(JSON.toJSONString(message));
                response.getWriter().println(JSON.toJSONString(roles));
//                response.getWriter().println(JSON.toJSONString(message, filter));
//                logger.debug("autorized");
            }
        } catch (SQLException e) {
            message.put("message", "数据库操作异常");
            //响应message到前端
            response.getWriter().println(JSON.toJSONString(message));
            e.printStackTrace();
        } catch (Exception e) {
            message.put("message", "网络异常");
            e.printStackTrace();
            //响应message到前端
            response.getWriter().println(JSON.toJSONString(message));
        }
    }
}
